﻿using System.Collections.Generic;
using System.Linq;
using System.ComponentModel.Composition;
using Caliburn.Micro;
using SS.WPF.Framework.ViewModel;
using SS.WPF.Framework.ViewModel.Container;
using SS.WPF.Framework.ViewModel.Navigation;

namespace TestFramework.ViewModels
{
    /// <summary>
    /// The class implements interface INavigation that is used to present a Navigation control
    /// </summary>
    [Export(typeof(INavigation))]
    public class NavigationViewModel: AllActiveViewModel<IScreen>, INavigation
    {
        private IEnumerable<INavigationCatalog> _navigationItems;

        /// <summary>
        /// Import instance of classes implement interface INavigationCatalog
        /// </summary>
        [ImportMany(typeof(INavigationCatalog))]
        public IEnumerable<INavigationCatalog> NavigationItems
        {
            get
            {
                return this._navigationItems;
            }
            set
            {
                this._navigationItems = value;
                this.ActivateAll();
                NotifyOfPropertyChange(() => NavigationItems);
            }
        }

        public bool IsDirty
        {
            get
            {
                foreach (var navigationCatalog in this.NavigationCatalogs)
                {
                    foreach (var item in navigationCatalog.NavigationItems)
                    {
                        var editable = item as IEditable;
                        if (editable != null)
                        {
                            if (editable.EditingStatus != EditingStatus.Error
                                && editable.EditingStatus != EditingStatus.None)
                            {
                                return true;
                            }
                        }
                    }
                }

                return false;
            }
        }

        /// <summary>
        /// Refer to instance of classes implement interface INavigationCatalog
        /// <para>
        /// This property is published for consumer 
        /// that using NavigationViewModel to expand or collapse NavigationNodes
        /// </para>
        /// </summary>
        public IEnumerable<INavigationCatalog> NavigationCatalogs
        {
            get
            {
                return this.Items.OfType<INavigationCatalog>().ToList();
            }
        }

        /// <summary>
        /// Active all NavigationCatelog
        /// </summary>
        private void ActivateAll()
        {
            if (this.NavigationItems != null)
            {
                foreach (var item in NavigationItems)
                {
                    var screen = item as IScreen;
                    if (screen != null)
                    {
                        screen.PropertyChanged += this.OnItemPropertyChanged;
                    }

                    this.Items.Add(screen);
                }
            }
        }

        void OnItemPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "IsDirty")
            {
                this.NotifyOfPropertyChange(() => this.IsDirty);
            }
        }

        /// <summary>
        /// Get all NavigationNodes of NavigationCatalogs
        /// </summary>
        /// <returns></returns>
        public IEnumerable<INavigationNode> GetAllNodes()
        {
            return this.NavigationCatalogs.
                SelectMany(navigationCatalog => navigationCatalog.NavigationItems).OfType<INavigationNode>();
        }
    }
}
